#ifndef __NOISE_HARD_SAMSUNG_AUDIOOUTPOOL_H__
#define __NOISE_HARD_SAMSUNG_AUDIOOUTPOOL_H__

#include "AutoPtr.h"

namespace Osp {
namespace Media {

class AudioOut;

} // namespace Media
} // namespace Osp

namespace liba {
namespace noise {
namespace hard {
namespace samsung {

class AudioOutPool;
struct PoolElement;

class AudioOutEvents
{
public:
	virtual void AudioOutEndOfBuffer() = 0;
};

class AudioOutHandle
{
	friend class AudioOutPoolImpl;
public:
	AudioOutHandle();
	// Move semantics
	AudioOutHandle(const AudioOutHandle& rhs);
	~AudioOutHandle();

	// Move semantics
	AudioOutHandle& operator=(const AudioOutHandle& rhs);
	Osp::Media::AudioOut* operator->() const;
	operator bool() const;

	void Subscribe(AudioOutEvents* subscriber);
	void Unsubscribe();

	void release();
private:
	AudioOutHandle(PoolElement* element, AudioOutPool* pool);
private:
	mutable PoolElement* element;
	mutable AudioOutPool* pool;
};

class AudioOutPoolImpl;

class AudioOutPool
{
public:
	static AudioOutPool* GetInstance();
	~AudioOutPool();

	AudioOutHandle Request(bool stereo);
	void Release(AudioOutHandle& handle);
private:
	AudioOutPool();

	AudioOutPoolImpl* impl;
private:
	static AutoPtr<AudioOutPool> instance;
};

} // namespace samsung
} // namespace hard
} // namespace noise
} // namespace liba

#endif /* __NOISE_HARD_SAMSUNG_AUDIOOUTPOOL_H__ */
